package edu.pku.sei.transformation.editor.model.test;

import java.util.ArrayList;
import java.util.List;

import org.w3c.dom.Element;

import edu.pku.sei.gefcommon.descriptor.annotation.EnumerationProperty;
import edu.pku.sei.gefcommon.descriptor.annotation.MethodProperty;
import edu.pku.sei.modeler.model.xml.XMLUtility;
import edu.pku.sei.transformation.editor.model.ModelPackage;
import edu.pku.sei.transformation.editor.model.base.NamedElement;
import edu.pku.sei.transformation.editor.model.constraint.ConstraintConnection;
import edu.pku.sei.transformation.editor.model.constraint.IConstrainableElement;

public class CheckPoint extends NamedElement implements IConstrainableElement {
	private int state = STATE_NONE;
	public static final int STATE_SUCCEED = 1;
	public static final int STATE_FAIL = -1;
	public static final int STATE_NONE = 0;
	
//	public static final int TYPE_ASSERT_TRUE = 0X0;
//	public static final int TYPE_ASSERT_FALSE = 0X1;
//	public static final int TYPE_ASSERT_NULL = 0X2;
//	public static final int TYPE_ASSERT_NOT_NULL = 0X3;
//	public static final int TYPE_ASSERT_EQUAL = 4;
//	public static final int TYPE_ASSERT_NOT_EQUAL = 5;
//	protected int type;
//	private static final String[] typeStrings = new String[]{"Assert True","Assert False","Assert Null","Assert Not Null", "Assert Equal","Assert Not Equal"};
	private ArrayList<ConstraintConnection> constraintConnections = new ArrayList<ConstraintConnection>(); 
	protected ArrayList<CheckPointOperand> operands = new ArrayList<CheckPointOperand>();
	
	public boolean canAddOperand() {
//		switch(type) {
//		case TYPE_ASSERT_TRUE:
//		case TYPE_ASSERT_FALSE:
//		case TYPE_ASSERT_NULL:
//		case TYPE_ASSERT_NOT_NULL:
//			return operands.size() == 0;
//		case TYPE_ASSERT_EQUAL:
//		case TYPE_ASSERT_NOT_EQUAL:
//			return operands.size() < 2;
//		default:
//			return false;
//		}
		return true;
	}
	public boolean addOperand(CheckPointOperand operand) {
		if (canAddOperand())
			return operands.add(operand);
		else
			return false;
	}
	public boolean removeOperand(CheckPointOperand operand) {
		return operands.remove(operand);
	}
	
	
//	public int getType() {
//		return type;
//	}
//	
//	public void setType(int newValue) {
//		if (this.type != newValue) {
//			int oldValue = this.type;
//			this.type = newValue;
//			firePropertyChange(ModelPackage.CHECK_POINT_TYPE, oldValue, newValue);
//		}
//	}
	
//	@MethodProperty(id = ModelPackage.CHECK_POINT_TYPE, catalog = "Check Point", name = "type", setter = "setTypeString")
//	@EnumerationProperty(function = "getTypeStrings")
//	public String getTypeString() {
//		switch(type) { 
//		case TYPE_ASSERT_TRUE:
//			return typeStrings[0];
//		case TYPE_ASSERT_FALSE:
//			return typeStrings[1];
//		case TYPE_ASSERT_NULL:
//			return typeStrings[2];
//		case TYPE_ASSERT_NOT_NULL:
//			return typeStrings[3];
//		case TYPE_ASSERT_EQUAL:
//			return typeStrings[4];
//		case TYPE_ASSERT_NOT_EQUAL:
//			return typeStrings[5];
//		default:
//			return typeStrings[0];
//		}
//	}
	
//	public void setTypeString(String s) {
//		if (typeStrings[0].equals(s)) {
//			setType(TYPE_ASSERT_TRUE);
//		} else if (typeStrings[1].equals(s)) {
//			setType(TYPE_ASSERT_FALSE);
//		} else if (typeStrings[2].equals(s)) {
//			setType(TYPE_ASSERT_NULL);
//		} else if (typeStrings[3].equals(s)) {
//			setType(TYPE_ASSERT_NOT_NULL);
//		} else if (typeStrings[4].equals(s)) {
//			setType(TYPE_ASSERT_EQUAL);
//		} else if (typeStrings[5].equals(s)) {
//			setType(TYPE_ASSERT_NOT_EQUAL);
//		}
//	}
	
//	public Object[] getTypeStrings() {
//		return typeStrings;
//	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	
	@Override
	public void serialize(Element root) {
		super.serialize(root);
		XMLUtility.xmlInstance.serializeAttribute(root, ModelPackage.CHECK_POINT_STATE, state);
//		XMLUtility.xmlInstance.serializeAttribute(root, ModelPackage.CHECK_POINT_TYPE, type);
		XMLUtility.xmlInstance.serializeNodes(root, ModelPackage.CHECK_POINT_OPERANDS, operands);
		XMLUtility.xmlInstance.serializeNodes(root, ModelPackage.CHECK_POINT_CONSTRAINT, constraintConnections);
	}
	
	@Override
	public void deSerialize(Element root) {
		super.deSerialize(root);
		state = XMLUtility.xmlInstance.deSerializeInt(root, ModelPackage.CHECK_POINT_STATE);
//		type = XMLUtility.xmlInstance.deSerializeInt(root, ModelPackage.CHECK_POINT_TYPE);
		this.operands.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ModelPackage.CHECK_POINT_OPERANDS));
		this.constraintConnections.addAll(XMLUtility.xmlInstance.deSerializeNodes(root, ModelPackage.CHECK_POINT_CONSTRAINT));
	}
	
	@Override
	public String toString() {
		if (getName() == null && getName().equals(""))
			return "unnamed checkpoint";
		else
			return getName();
	}
	@Override
	public List<ConstraintConnection> getConstraintConnections() {
		return this.constraintConnections;
	}
	
}
